package com.rtsapp.server.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 反射的通用工具类
 *
 * @author zhangbin
 */
public class ReflectionUtils {

    public static Object setFieldsValue(Object object, String fieldName, Object fieldValue) {
        try {
            Class<?> obj = object.getClass();
            Field field = obj.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, fieldValue);
            field.setAccessible(false);
            return object;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Object getFieldsValue(Object object, String fieldName) {
        try {
            Class<?> obj = object.getClass();
            Field field = obj.getDeclaredField(fieldName);
            field.setAccessible(true);
            Object value = field.get(object);
            field.setAccessible(false);
            return value;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Class<?> getFieldsType(Object object, String fieldName) {
        try {
            Class<?> obj = object.getClass();
            Field field = obj.getDeclaredField(fieldName);
            field.setAccessible(true);
            Class<?> value = field.getType();
            field.setAccessible(false);
            return value;
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Object invoketMethod(Object object, String methodName,
                                       Object... args) {
        try {
            Class<?> obj = object.getClass();
            Class<?>[] argTypes = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                argTypes[i] = args[i].getClass();
            }
            Method method = obj.getDeclaredMethod(methodName, argTypes);
            method.setAccessible(true);
            Object returnObject = method.invoke(object, args);
            method.setAccessible(true);
            return returnObject;
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * get type name.
     * java.lang.Object[][].class => "java.lang.Object[][]"
     * @param c class.
     * @return name.
     */
    public static String getTypeName(Class<?> c)
    {
        if( c.isArray() )
        {
            StringBuilder sb = new StringBuilder();
            do
            {
                sb.append("[]");
                c = c.getComponentType();
            }
            while( c.isArray() );

            return c.getName() + sb.toString();
        }
        return c.getName();
    }
}